//
//  SSDK_UserSystem.m
//  DDUITest
//
//  Created by wyht－ios－dev on 15/11/6.
//  Copyright © 2015年 WYHT. All rights reserved.
//

#import "OpenSDK.h"
#import "OpenSDK_Enum.h"
#import "OpenSDK_DataManager.h"
#import "OpenSDK_HttpUtil.h"
#import "OpenSDK_DataKeys.h"
#import "OpenSDK_LoginManager.h"
#import "OpenSDK_PayManager.h"
#import "OpenSDK_LocalRecord.h"
#import "OpenSDK_InitResData.h"
#import "OpenSDK_EventManager.h"
#import "OpenSDK_EventKeys.h"
#import "OpenSDK_UIManager.h"
#import "OpenSDK_StatusManager.h"
#import "OpenSDK_StatisticsManager.h"
#import "OpenSDK_UIUtil.h"
#import "OPKWebViewController.h"
#import "OpenSDK_Toast.h"
#import "OpenSDK_SdkProtrol.h"
#import "OpenSDK_LoginProtocol.h"
#import "OpenSDK_PayProtocol.h"

#import "OPKMach.h"
#import "OpenSDK_JsonUtil.h"
#import "OPKTracking.h"
#import <Y2Common/Y2Common.h>

@implementation OpenSDK

{
    bool initFlag;
    bool initSuccess;
    NSArray *loginSdkNames;// 目前支持的登录sdk类名
    NSArray *paySdkNames;// 目前支持的支付sdk类
    NSMutableArray *localLoginServerNames;  // 本地登录相关Server名
    NSMutableArray *localPaySdkServerNames; // 本地支付相关Server名
    UILabel *toastLabel;
}

// OpenSDK地址
static NSString *OPENSDK_URL = @"https://opensdk.sail2world.com/opensdk-router";


// OpenSDK版本号(更新必改，和pod版本号保持一致)
static NSString *OPENSDK_VERSION = @"0.2.5";

static OpenSDK *instance = nil;

+(instancetype) getInstance {
    if (instance==nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[self alloc] init];
            if (@available(iOS 13.0, *)) {
                instance->loginSdkNames = @[@"WechatLogin",
                                            @"AppleLogin",
                                            @"QQ",
                                            @"OneKeyLogin"];
            } else {
                instance->loginSdkNames = @[@"WechatLogin",
                                            @"QQ"];
            }
            instance->paySdkNames = @[@"ApplePay",
                                      @"AliPay",
                                      @"WcXyz",
                                      @"UPPay",
                                      @"PayNow",
                                      @"DianLiangPay"];
//            instance->adTrackSdkNames = @[@"AppsFlyerTrack",
//                                          @"FackBookTrack",
//                                          @"FireBaseTrack"]
            instance->localLoginServerNames = [[NSMutableArray alloc] initWithCapacity:0];
            instance->localPaySdkServerNames = [[NSMutableArray alloc] initWithCapacity:0];
        });
    }
    return instance;
}

-(void) initWithDelegate:(id<OpenSDK_Delegate>)delegate {
    initFlag = NO;
    self.delegate = delegate;
    //获取channelID
    NSString *channelValue;
    NSString *pubkeyValue;
    NSString *appIDValue;
    NSDictionary *data = [[NSBundle mainBundle] infoDictionary];
    NSDictionary *config = [data objectForKey:OpenSDK_CONFIG];
    if (config != nil) {
        channelValue=[config valueForKey:OpenSDK_CHANNELID];
        pubkeyValue=[config valueForKey:OpenSDK_PUBKEY];
        appIDValue=[config valueForKey:OpenSDK_APPID];
    } else {
        [delegate openSDKInitWithCode:OpenSDK_INIT_FAIL errStr:@"init fail, can not find opsdk_config"];
        return;
    }
    
    // 设置opensdk版本号
    [[OpenSDK_DataManager getInstance] setVersion:OPENSDK_VERSION];
    
    //必须配置OpenSDK_AppID
    if (appIDValue == nil) {
        [delegate openSDKInitWithCode:OpenSDK_INIT_FAIL errStr:@"init fail, can not find appID"];
        return;
    } else {
        [[OpenSDK_DataManager getInstance] setAppID:appIDValue];
    }
    
    //必须置OpenSDK_PubKey，用于后面的加密
    if(pubkeyValue == nil) {
        [delegate openSDKInitWithCode:OpenSDK_INIT_FAIL errStr:@"init fail, can not find pubkey"];
        return;
    } else {
        [[OpenSDK_DataManager getInstance] setAppPubKey:pubkeyValue];
    }
    
    //必须配置ChannelID
    if (channelValue == nil) {
        [delegate openSDKInitWithCode:OpenSDK_INIT_FAIL errStr:@"init fail, can not find channelID"];
        return;
    } else {
        [[OpenSDK_DataManager getInstance] setChannelID:channelValue];
    }
    
    //配置OpenSDK服务器地址
    NSString *debugUrl = [config valueForKey:OpenSDK_DEBUG_URL];
    if (debugUrl == nil || debugUrl.length == 0) {
        //如果没有配置Debug地址，则使用正式地址
        [[OpenSDK_DataManager getInstance] setUrl:OPENSDK_URL];
    } else {
        //如果配置了Debug地址，则使用Debug地址地址
        [[OpenSDK_DataManager getInstance] setUrl:debugUrl];
    }
    
    NSMutableDictionary *supportSDKs = [[NSMutableDictionary alloc] init];
    NSMutableDictionary *supportSDKServerNames = [[NSMutableDictionary alloc] init];
    //获取项目导入的支付SDK
    localPaySdkServerNames = [[NSMutableArray alloc] init];
    for (NSString *sdkName in paySdkNames) {
        id<OpenSDK_SdkProtrol> sdkClass = [[OpenSDK_DataManager getInstance].supportSDKs objectForKey:sdkName];
        if (sdkClass == nil) {
            sdkClass = [[NSClassFromString(sdkName) alloc] init];
        }
        if (sdkClass != nil && [sdkClass conformsToProtocol:@protocol(OpenSDK_SdkProtrol)]) {
            // 加入到sdk集合
            [supportSDKs setObject:sdkClass forKey:sdkName];
            [supportSDKServerNames setObject:sdkClass forKey:[sdkClass getServerName]];
            // 如果是支付sdk，加入到本地支付方式列表中
            if ([sdkClass conformsToProtocol:@protocol(OpenSDK_PayProtocol)]) {
                [localPaySdkServerNames addObject:[sdkClass getServerName]];
            }
        }
    }
    
    //获取项目导入的登录SDK
    localLoginServerNames=[[NSMutableArray alloc] init];
    [localLoginServerNames addObject:OpenSDK_S_DYNAMIC];//默认带上动态手机登录
    [localLoginServerNames addObject:OpenSDK_S_ACCOUNT];//默认带上邮箱登录
    for (NSString *sdkName in loginSdkNames) {
        id<OpenSDK_SdkProtrol> sdkClass = [[OpenSDK_DataManager getInstance].supportSDKs objectForKey:sdkName];
        if (sdkClass == nil) {
            sdkClass = [[NSClassFromString(sdkName) alloc] init];
        }
        if (sdkClass != nil && [sdkClass conformsToProtocol:@protocol(OpenSDK_SdkProtrol)]) {
            // 加入到sdk集合
            [supportSDKs setObject:sdkClass forKey:sdkName];
            [supportSDKServerNames setObject:sdkClass forKey:[sdkClass getServerName]];
            // 如果是登录sdk，加入到本地登录方式列表中
            if ([sdkClass conformsToProtocol:@protocol(OpenSDK_LoginProtocol)]) {
                [localLoginServerNames addObject:[sdkClass getServerName]];
            }
        }
    }

    //获取所有第三方登录、支付的SDK
    [[OpenSDK_DataManager getInstance] setSupportSDKs:supportSDKs];
    [[OpenSDK_DataManager getInstance] setSupportSDKServerNames:supportSDKServerNames];
    
    // 直接回调成功，获取配置放在登录
    [self.delegate openSDKInitWithCode:OpenSDK_INIT_SUCCESS errStr:nil];
    initFlag = true;
}

- (void)alert:(NSString *)msg {
    
    if (!toastLabel) {
        CGRect screenRect = [UIScreen mainScreen].bounds;
        CGSize itemSize = CGSizeMake(200, 40);

        toastLabel = [[UILabel alloc] initWithFrame:CGRectMake((screenRect.size.width - itemSize.width) / 2.0, (screenRect.size.height - itemSize.height) / 2.0, itemSize.width, itemSize.height)];
        toastLabel.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.6];
        toastLabel.textColor = [UIColor whiteColor];
        toastLabel.textAlignment = NSTextAlignmentCenter;
        [[UIApplication sharedApplication].keyWindow addSubview:toastLabel];
    }

    toastLabel.text = msg;
    [toastLabel setHidden:false];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self->toastLabel setHidden:YES];
    });
}


-(void) login {
    // 是否调用了init，没有则返回失败
    if (!initFlag) {
        [self.delegate openSDKLoginWithCode:OpenSDK_LOGIN_FAIL userInfo:nil errStr:@"login fail, please init first"];
        return;
    }
    
    // 已初始化，则直接调用登录
    if (initSuccess) {
        //根据主题显示UI，根据配置的登录方式显示
        [[OpenSDK_UIManager getInstance] initLoginUI];
        return;
    }
    initSuccess = NO;
    // 为初始化，则获取配置，成功后调用登录
    // 获取服务器端配置
    [OpenSDK_HttpUtil initWithDelegate:^(OpenSDK_BaseResData *resData) {
        if ([resData isOk]) {
            OpenSDK_InitResData *initData=[[OpenSDK_InitResData alloc] initWithData:[resData content]];
            [[OpenSDK_DataManager getInstance] setSecret_key:[initData getSecretKey]];
            [OpenSDK_DataManager getInstance].isPayToastEnable = [initData isPayToastEnable];
            [OpenSDK_DataManager getInstance].isAppstoreReview = [initData getAppStoreReviewStatus];
            [[OpenSDK_DataManager getInstance] setNeedActiveCodeFlag:[initData getLoginAndRegisterActiveCodeFlag]];
            [[OpenSDK_DataManager getInstance] setActiveAffectData:[initData getActiveAffectData]];
            [[OpenSDK_DataManager getInstance] setForbidGuestPayFlag:[initData getForbidGuestPayFlag]];
            // 用户协议显示开关
            [[OpenSDK_DataManager getInstance] setShowContranct:[initData getShowContract]];
            // 用户协议勾选状态开关
            [[OpenSDK_DataManager getInstance] setContranctChecked:[initData getContractChecked]];
            // 用户协议web页面地址
            [[OpenSDK_DataManager getInstance] setContractWebUrl:[initData getContractWebURL]];
            // 隐私协议web页面地址
            [[OpenSDK_DataManager getInstance] setPrivacyWebUrl:[initData getPrivacyWebURL]];
            
            // 用户中心
            [[OpenSDK_DataManager getInstance] setUserCenterUrl:[initData getUserCenterURL]];
            //设置服务器端的注册配置
            [[OpenSDK_DataManager getInstance] setSupportRegisterTypes:[initData getSupportRegisterTypes]];
            if ([OpenSDK_DataManager getInstance].supportRegisterTypes == nil) {
                [OpenSDK_DataManager getInstance].supportRegisterTypes = [[NSArray alloc] init];
            }
            
            //服务器端的登录配置，和本地登录配置，求交集，得出用户可选的登录方式
            NSArray *serverLoginTypes = [initData getSupportLoginTypes];
            NSMutableArray *finalLoginTypes=[[NSMutableArray alloc] init];
            if (serverLoginTypes != nil) {
                for (id loginType in serverLoginTypes) {
                    if ([self->localLoginServerNames containsObject:loginType]) {
                        [finalLoginTypes addObject:loginType];
                    }
                }
            }
            if (finalLoginTypes.count == 0) {
                // 如果服务器端没有配置，则默认提供手机登录
                [finalLoginTypes addObject:OpenSDK_S_DYNAMIC];
            }
            
            // 根据配置处理开关
            if ([finalLoginTypes containsObject:OpenSDK_S_ONE_KEY]) {
                NSUInteger onekeyVal = [initData getOneKeyRote];
                NSUInteger deviceHash = [[Y2DeviceInfo getDeviceID] hash];
                NSUInteger result = deviceHash % 100;
                if (result > onekeyVal || ![initData getOneKeySwitch]) {
                    [finalLoginTypes removeObject:OpenSDK_S_ONE_KEY];
                }
            }
            if ([OpenSDK_DataManager getInstance].isAppstoreReview){
                if (![finalLoginTypes containsObject:OpenSDK_S_TEMPORARY]){
                    [finalLoginTypes addObject:OpenSDK_S_TEMPORARY];
                }
                if (![finalLoginTypes containsObject:OpenSDK_S_ACCOUNT]){
                    [finalLoginTypes addObject:OpenSDK_S_ACCOUNT];
                }
            }else{
                if ([finalLoginTypes containsObject:OpenSDK_S_TEMPORARY]){
                    [finalLoginTypes removeObject:OpenSDK_S_TEMPORARY];
                }
            }
            
            [[OpenSDK_DataManager getInstance] setSupportLoginTypes:finalLoginTypes];
            
            //服务器支付配置，和本地支付配置，求交集，得出用户可选的支付方式
            NSArray *serverPayTypes = [initData getSupportXyzTypes];
            NSMutableArray *finalPayTypes=[[NSMutableArray alloc] init];
            if (serverPayTypes != nil) {
                for (id payType in serverPayTypes) {
                    if ([self->localPaySdkServerNames containsObject:payType]) {
                        [finalPayTypes addObject:payType];
                    }
                }
            }
            if (finalPayTypes.count == 0 && [self->localPaySdkServerNames containsObject:@"ApplePay"]) {
                // 如果服务器端没有配置，且本地配置了苹果支付，则默认使用苹果支付
                [finalPayTypes addObject:@"ApplePay"];
            }
            
            [[OpenSDK_DataManager getInstance] setSupportXyzTypes:finalPayTypes];
            
            //设置国家区号信息
            [[OpenSDK_DataManager getInstance] setCountryCodeInfo:[initData getCountryCodeFromServer]];
            
            // 存储本地国家编码
            NSDictionary *currentCountryInfo = [[OpenSDK_DataManager getInstance] getCountryCodeFromCurMachine];
            [[OpenSDK_LocalRecord getInstance] saveData:OpenSDK_L_COUNTRY_CODE value:[currentCountryInfo objectForKey:OpenSDK_S_COUNTRY_CODE]];
           
            // 设置滑块解锁地址
            [[OpenSDK_DataManager getInstance] setImgVerificationUrl:[initData getImgVerificationUrl]];
            
            // 设置UI Style
            [[OpenSDK_DataManager getInstance] setUiStyle:[initData getUIStyle]];
            
            //如果有需要初始化的模块，则进行相关初始化操作
            [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_INIT object:nil];
            
            self->initSuccess = YES;
            //回调初始化成功
            dispatch_async(dispatch_get_main_queue(), ^{
//                [self.delegate openSDKInitWithCode:OpenSDK_INIT_SUCCESS errStr:nil];
                //根据主题显示UI，根据配置的登录方式显示
                [[OpenSDK_UIManager getInstance] initLoginUI];
            });
            NSLog(@"OpenSDK_INIT_SUCCESS");
        } else {
            //回调初始化失败
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate openSDKLoginWithCode:OpenSDK_LOGIN_FAIL userInfo:nil errStr:@"login fail, please init first"];
            });
        }
    }];
}

-(void) payWithPayInfo:(OpenSDK_PayInfo *)payInfo {
    if (![self IsLogin]) {
        [self.delegate openSDKPayWithCode:OpenSDK_PAY_FAIL orderInfo:nil errStr:@"pay fail,userInfo is null"];
        return;
    }
    //游客模式，不进行支付
    if ([OpenSDK_DataManager getInstance].isAppstoreReview && [OpenSDK_DataManager getInstance].currentAccount.accountType == OpenSDKAccountTypeGuest){
        dispatch_async(dispatch_get_main_queue(), ^{
            OpenSDK_iToast *toast = [OpenSDK_iToast makeText:@"根据国家相关政策和规定，需要对玩家付费行为和数据进行安全保障。游客账号仅作为一种临时凭证，更换设备、游戏卸载后都有丢失账号风险，建议完成手机绑定和实名认证后再进行付费充值。"];
            [toast setDuration: OpenSDK_iToastDurationNormal];
            [toast show];
        });
        [self.delegate openSDKPayWithCode:OpenSDK_PAY_CANCEL orderInfo:nil errStr:@"fail,Tourists are forbidden to pay"];
        return;
    }
    
    float orderAmout=[[payInfo orderAmount] floatValue];
    if (orderAmout == 0) {
        [self.delegate openSDKPayWithCode:OpenSDK_PAY_FAIL orderInfo:nil errStr:@"pay fail,OrderAmount is illegal. Please make sure OrderAmount is a number string and bigger than 0!"];
        return;
    }
    
    //补全支付回调地址和支付货币类型
    NSString *currency;
    NSString *paybackUrl;
    NSDictionary *config = [[[NSBundle mainBundle] infoDictionary] objectForKey:OpenSDK_CONFIG];
    if (config != nil) {
        paybackUrl = [config valueForKey:OpenSDK_PAYBACKURL];
        if (paybackUrl != nil && [paybackUrl length]>0) {
            [payInfo setNotifyUrl:paybackUrl];
        }
        currency = [config valueForKey:OpenSDK_CURRENCY];
        if (currency == nil) {
            [self.delegate openSDKPayWithCode:OpenSDK_PAY_FAIL orderInfo:nil errStr:@"pay fail, can not find currency value"];
            return;
        } else {
            [payInfo setCurrency:currency];
        }
    } else {
        [self.delegate openSDKPayWithCode:OpenSDK_PAY_FAIL orderInfo:nil errStr:@"pay fail, can not find opsdk_config"];
        return;
    }
    
    //显示支付UI
    [[OpenSDK_UIManager getInstance] initPayUIWithPayInfo:payInfo];
}

-(void) logout {
    [[OpenSDK_LoginManager getInstance] localLogout];
}

-(BOOL) IsLogin {
    if ([[OpenSDK_LoginManager getInstance] curOpenId]==nil)
        return NO;
    else
        return YES;
}

- (void)userCenter {
    if ([self IsLogin]) {
        OPKWebViewController *webViewController = [[OPKWebViewController alloc] init];
        webViewController.url = [OpenSDK_DataManager getInstance].userCenterUrl;
//        webViewController.url = @"http://172.20.1.50:8080/#/";
        UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:webViewController];
        [navController setNavigationBarHidden:YES];
        navController.modalPresentationStyle = UIModalPresentationOverFullScreen;
        UIViewController *root = [OpenSDK_UIUtil getCurrentVC];
        [root presentViewController:navController animated:YES completion:nil];
    } else {
        [self login];
    }
}

// 既然怒游戏
- (void)enteredGame:(NSDictionary *)data {
    if (_currentGameRole == nil) {
        _currentGameRole = [[OPKGameRoleModel alloc] init];
    }
    _currentGameRole.roleId = [data objectForKey:@"roleId"];
    _currentGameRole.roleName = [data objectForKey:@"roleName"];
    _currentGameRole.zoneId = [data objectForKey:@"zoneId"];
    _currentGameRole.zoneName = [data objectForKey:@"zoneName"];
    _currentGameRole.roleLevel = [data objectForKey:@"roleLevel"];
    _currentGameRole.roleBalance = [data objectForKey:@"roleBalance"];
    [OpenSDK_EventManager postNotificationName:OPENSDK_ENTERED_GAME object:_currentGameRole];
}

//切换账号功能，直接清空本地数据，登出成功消息
-(void) switchAccount {
    //不清除本地数据，方便游客登陆
    [[OpenSDK_LocalRecord getInstance] delLocalData];
    [[OpenSDK getInstance] logout];
}

+(void) applicationDidBecomeActive:(UIApplication *)application {
    // 进入应用，要解开支付锁
    [[OpenSDK_StatusManager getInstance] setPayStatus:NO];
    
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATIONDIDBECOMEACTIVE object:dic];
}

+(void) applicationWillEnterForeground:(UIApplication *)application {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATIONWILLENTERFOREGROUND object:dic];
}

+(void) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [dic setValue:launchOptions forKey:OpenSDK_E_DIDFINISHLAUNCHWITHOPTIONS];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_DIDFINISHLAUNCHINGWITHOPTIONS object:dic];
    
    // config
    [[OPKTracking shared] config];
}

+(void) application:(id)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [dic setValue:url forKey:OpenSDK_E_OPENURL];
    [dic setValue:sourceApplication forKey:OpenSDK_E_SOURCEAPPLICATION];
    [dic setValue:annotation forKey:OpenSDK_E_ANNOTATION];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_OPENURL_SOURCEAPPLICATION_ANNOTATION object:dic];
}

+(void) application:(id)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:app forKey:OpenSDK_E_APPLICATION];
    [dic setValue:url forKey:OpenSDK_E_OPENURL];
    [dic setValue:options forKey:OpenSDK_E_OPTIONS];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_OPENURL_OPTIONS object:dic];
}

+(void) application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [dic setValue:url forKey:OpenSDK_E_OPENURL];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_HANDLEOPENURL object:dic];
}

+ (void)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [dic setValue:userActivity forKey:OpenSDK_E_USERACTIVITY];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_CONTINUEUSERACTIVITY object:dic];
}

+ (void)applicationWillTerminate:(UIApplication *)application {
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setValue:application forKey:OpenSDK_E_APPLICATION];
    [OpenSDK_EventManager postNotificationName:OPENSDK_EVENT_APPLICATION_WILL_TERMINATE object:dic];
}

@end

